﻿using System;
using System.Diagnostics;
using System.IO;

using Flood.Extensions;
using Flood.FloodStrategies;

namespace Flood
{
	internal class Program
	{
		private const string INPUT_FILE = @".\tiles.txt";
		private const string OUTPUT_FILE = @".\results.txt";

		public static void Main()
		{
			// 33, 16, gets 20442 moves in 8816 seconds
			// see readme.txt for more results
			const int generation = 500;
			const int population = 16;
			int totalMoves = TestVariant(generation, population);
			Console.WriteLine("Total moves = " + totalMoves);
		}

		private static int TestVariant(int maxGenerationsWithoutImprovement,
		                               int maxPopulationSize)
		{
			PuzzleConstants puzzleConstants = new PuzzleConstants(25,
			                                                      14,
			                                                      14,
			                                                      false);

			PuzzleRepository puzzleRepository = new PuzzleRepository(new DataReader(INPUT_FILE),
			                                                         puzzleConstants);

			int totalMoves = 0;
			int puzzlesSolved = 0;
			using (StreamWriter output = new StreamWriter(OUTPUT_FILE))
			{
				foreach (Puzzle puzzle in puzzleRepository.GetPuzzles())
				{
					Result solution =
						puzzle.Flood(
							new FloodAdjacentColorSelectedGenetically(puzzleConstants,
							                                          maxGenerationsWithoutImprovement,
							                                          maxPopulationSize),
							puzzleConstants.MaxFloods);
					string fillSteps = solution.FillSteps.ConvertToString();
					output.WriteLine(fillSteps);
					output.Flush();
					totalMoves += fillSteps.Length;
					puzzlesSolved++;
					WriteOutput(puzzlesSolved);
				}
			}

			return totalMoves;
		}

		[Conditional("DEBUG")]
		[Conditional("DETAILED")]
		[Conditional("MINIMAL")]
		private static void WriteOutput(int puzzlesSolved)
		{
			if (puzzlesSolved % 50 == 0)
			{
				Console.WriteLine(puzzlesSolved + " puzzles completed");
			}
		}
	}
}